<?php
class UcApplication extends CWebApplication
{
	public $defaultController = 'Uc';

	private $route = '';

	protected function preinit()
	{
		$this->parseRequest();
	}

	private function parseRequest()
	{
		//ucenter
		Yii::import('application.vendors.*');
		include_once 'ucenter.php';
		
		error_reporting(0);
		set_magic_quotes_runtime(0);
		
		defined('MAGIC_QUOTES_GPC') || define('MAGIC_QUOTES_GPC', get_magic_quotes_gpc());
	
		$_DCACHE = $get = $post = array();
		
		$code = null;
		if(isset($_GET['code'])) {
			$code = @$_GET['code'];
		}
		else if(isset($_POST['code'])) {
			$code = @$_POST['code'];
		}
		else {
			exit('Missing Parameter');
		}
		
		parse_str($this->_authcode($code, 'DECODE', UC_KEY), $get);
		if(MAGIC_QUOTES_GPC) {
			$get = _stripslashes($get);
		}
		
		if(empty($get)) {
			exit('Invalid Request');
		}
		
		$timestamp = time();
		if($timestamp - $get['time'] > 3600) {
			exit('Authracation has expiried');
		}
		
		$action = $get['action'];
		if(!in_array($action, array('test', 'deleteuser', 'renameuser', 'gettag', 'synlogin', 'synlogout', 'updatepw', 'updatebadwords', 'updatehosts', 'updateapps', 'updateclient', 'updatecredit', 'getcreditsettings', 'updatecreditsettings')))
		{
			exit(API_RETURN_FAILED);
		}
		
		require_once 'uc_client/lib/xml.class.php';
		
		$post = xml_unserialize(file_get_contents('php://input'));

		$_GET = $get;
		$_POST = $post;
		
		if(YII_DEBUG == true) {
			$apilog = UC_ACTION_LOG;
			$f = fopen($apilog, 'a');
			if($f) {
				$content = $_SERVER[REQUEST_URI]."\r\n";
				foreach ($_GET as $k => $v) {
					$content = $content.'  '.$k.'='.$v."\r\n";
				}
				fwrite($f, $content);
				fclose($f);
			}
			else {
				exit('Open UC action log fail');
			}
		}
		
		// proceed to execute action
		$this->route = $this->defaultController .'/'. $action;
	}

	public function processRequest()
	{
		$this->runController($this->route);
	}

	private function _authcode($string, $operation = 'DECODE', $key = '', $expiry = 0) {
		
		$ckey_length = 4;	// 随机密钥长度 取值 0-32;
		// 加入随机密钥，可以令密文无任何规律，即便是原文和密钥完全相同，加密结果也会每次不同，增大破解难度。
		// 取值越大，密文变动规律越大，密文变化 = 16 的 $ckey_length 次方
		// 当此值为 0 时，则不产生随机密钥
	
		$key = md5($key ? $key : UC_KEY);
		$keya = md5(substr($key, 0, 16));
		$keyb = md5(substr($key, 16, 16));
		$keyc = $ckey_length ? ($operation == 'DECODE' ? substr($string, 0, $ckey_length): substr(md5(microtime()), -$ckey_length)) : '';
	
		$cryptkey = $keya.md5($keya.$keyc);
		$key_length = strlen($cryptkey);
	
		$string = $operation == 'DECODE' ? base64_decode(substr($string, $ckey_length)) : sprintf('%010d', $expiry ? $expiry + time() : 0).substr(md5($string.$keyb), 0, 16).$string;
		$string_length = strlen($string);
	
		$result = '';
		$box = range(0, 255);
	
		$rndkey = array();
		for($i = 0; $i <= 255; $i++) {
			$rndkey[$i] = ord($cryptkey[$i % $key_length]);
		}
	
		for($j = $i = 0; $i < 256; $i++) {
			$j = ($j + $box[$i] + $rndkey[$i]) % 256;
			$tmp = $box[$i];
			$box[$i] = $box[$j];
			$box[$j] = $tmp;
		}
	
		for($a = $j = $i = 0; $i < $string_length; $i++) {
			$a = ($a + 1) % 256;
			$j = ($j + $box[$a]) % 256;
			$tmp = $box[$a];
			$box[$a] = $box[$j];
			$box[$j] = $tmp;
			$result .= chr(ord($string[$i]) ^ ($box[($box[$a] + $box[$j]) % 256]));
		}
	
		if($operation == 'DECODE') {
			if((substr($result, 0, 10) == 0 || substr($result, 0, 10) - time() > 0) && substr($result, 10, 16) == substr(md5(substr($result, 26).$keyb), 0, 16)) {
				return substr($result, 26);
			} else {
				return '';
			}
		} else {
			return $keyc.str_replace('=', '', base64_encode($result));
		}
	
	}

	private function _stripslashes($string) {
		if(is_array($string)) {
			foreach($string as $key => $val) {
				$string[$key] = $this->_stripslashes($val);
			}
		} else {
			$string = stripslashes($string);
		}
		return $string;
	}
}